/*
 * @Descripttion: toolkit的createAsyncThunk模块
 * @Author: lukasavage
 * @Date: 2021-12-08 21:32:33
 * @LastEditors: lukasavage
 * @LastEditTime: 2021-12-08 21:40:33
 */

import { createAction } from "./";

/**
 *
 * @param {string} typePrefix 类型的前缀
 * @param {*} payloadCreator actionCreator创建者
 */
function createAsyncThunk(typePrefix, payloadCreator) {
	let pending = createAction(typePrefix + "/pending", function () {
		return { payload: void 0 };
	});
	let fulfilled = createAction(typePrefix + "/fulfilled", function (payload) {
		return { payload };
	});
	let rejected = createAction(typePrefix + "/rejected", function (error) {
		return { error };
	});

	function actionCreator(arg) {
		return function (dispatch) {
			dispatch(pending());
			const promise = payloadCreator(arg);
			let abort;
			const abortedPromise = new Promise((_, reject) => {
				abort = () => {
					reject({ name: "AbortError", message: "Aborted" });
				};
			});
			Promise.race([promise, abortedPromise]).then(
				result => {
					return dispatch(fulfilled(result));
				},
				error => {
					return dispatch(rejected(error));
				}
			);
			return Object.assign(promise, { abort });
		};
	}
	return Object.assign(actionCreator, { pending, rejected, fulfilled });
}
export default createAsyncThunk;
